#include "fxcc/imgui/Editor.h"
#include "fxcc/core/graph/common/Lights.h"

using namespace fxcc::graph::common;
using namespace fxcc::imgui;


template <>
bool Editor::Edit<DirLight>(const std::string& label, DirLight& inst)
{
    EditInst<DirLight::Buffer>("buffer", inst.m_Buffer);
    return false;
}

template <>
bool Editor::Edit<DirLight::Buffer>(const std::string& label, DirLight::Buffer& inst)
{
    ColorInst<glm::vec3>("ambient", inst.ambient);
    CheckBoxInst<int>("ambientMap", inst.ambientMap);
    ColorInst<glm::vec3>("diffuse", inst.diffuse);
    CheckBoxInst<int>("diffuseMap", inst.diffuseMap);
    ColorInst<glm::vec3>("specular", inst.specular);
    CheckBoxInst<int>("specularMap", inst.specularMap);

    EditInst<glm::vec3>("direction", inst.direction);
    return false;
}

template <>
bool Editor::Edit<PointLight::Buffer>(const std::string& label, PointLight::Buffer& inst)
{
    ColorInst<glm::vec3>("ambient", inst.ambient);
    CheckBoxInst<int>("ambientMap", inst.ambientMap);
    ColorInst<glm::vec3>("diffuse", inst.diffuse);
    CheckBoxInst<int>("diffuseMap", inst.diffuseMap);
    ColorInst<glm::vec3>("specular", inst.specular);
    CheckBoxInst<int>("specularMap", inst.specularMap);

    EditInst<glm::vec3>("position", inst.position);
    EditInst<float>("constant", inst.constant);
    EditInst<float>("linear", inst.linear);
    EditInst<float>("quadratic", inst.quadratic);
    return false;
}

template <>
bool Editor::Edit<PointLight>(const std::string& label, PointLight& inst)
{
    EditInst<PointLight::Buffer>("m_Buffer", inst.m_Buffer);

    return false;
}

template <>
bool Editor::Edit<SpotLight::Buffer>(const std::string& label, SpotLight::Buffer& inst)
{
    ColorInst<glm::vec3>("ambient", inst.ambient);
    CheckBoxInst<int>("ambientMap", inst.ambientMap);
    ColorInst<glm::vec3>("diffuse", inst.diffuse);
    CheckBoxInst<int>("diffuseMap", inst.diffuseMap);
    ColorInst<glm::vec3>("specular", inst.specular);
    CheckBoxInst<int>("specularMap", inst.specularMap);

    EditInst<glm::vec3>("position", inst.position);
    EditInst<float>("cutOff", inst.cutOff);
    EditInst<glm::vec3>("direction", inst.direction);
    EditInst<float>("outCutOff", inst.outerCutOff);

    EditInst<float>("constant", inst.constant);
    EditInst<float>("linear", inst.linear);
    EditInst<float>("quadratic", inst.quadratic);
    return false;
}

template <>
bool Editor::Edit<SpotLight>(const std::string& label, SpotLight& inst)
{
    EditInst<SpotLight::Buffer>("m_Buffer", inst.m_Buffer);

    return false;
}
template <>
bool Editor::Edit<LightEffect>(const std::string& label, LightEffect& inst)
{
    int index = 0;
    if (TreeNode("DirLights", inst.Pad_0, index++))
    {
        ImGui::DragInt("num Dirs", &inst.numDirlights, 0, 0, MAX_DirNum - 1);
        for (int i = 0; i < inst.numDirlights; i++)
        {
            EditInst<DirLight>("dirLight", inst.dirlights[i]);
        }
        TreePop();
    }

    if (TreeNode("Pointlights", inst.Pad_0, index++))
    {
        ImGui::DragInt("num Point", &inst.numPoints, 0, 0, MAX_PointNum - 1);

        for (int i = 0; i < inst.numPoints; i++)
        {
            EditInst<PointLight>("pointLight", inst.pointLights[i]);
        }
        TreePop();
    }

    if (TreeNode("SpotLights", inst.Pad_0, index++))
    {
        ImGui::DragInt("num Spot", &inst.numSpotLights, 0, 0, MAX_SpotNum - 1);

        for (int i = 0; i < inst.numSpotLights; i++)
        {
            EditInst<SpotLight>("SpotLight", inst.spotLights[i]);
        }
        TreePop();
    }
    return false;
}
